﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.Runtime.Serialization.Json;
using System.IO;

namespace PC_Client
{
    delegate void ShowMainWindows(int onlineUserNum, List<string> onlineUserList);
    internal delegate void ShowWhisperWindows(string windowsName, string hostAndPort);

    public partial class LoginOn : Form
    {
        bool _isShow = false;
        private Main _main = null;
        private Socket _clientSocket = null;

        public LoginOn()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void LoginOn_Load(object sender, EventArgs e)
        {
            //CheckForIllegalCrossThreadCalls = false;
        }

        private readonly Unit _unit = new Unit();

        private void btnLoginOn_Click(object sender, EventArgs e)
        {
            string userName = this.txtUserName.Text.Trim();
            string pwd = this.txtPwd.Text.Trim();
            string name = this.txtName.Text.Trim();
            if (userName == string.Empty) { MessageBox.Show("请输入用户名!"); return; }
            if (pwd == string.Empty) { MessageBox.Show("请输入密码!"); return; }
            if (name == string.Empty) { MessageBox.Show("请输入名称!"); return; }

            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] output = md5.ComputeHash(Encoding.UTF8.GetBytes(pwd));

            string loginOnStr = userName + ";" + BitConverter.ToString(output).Replace("-", "") + ";" + name;

            MessagePackage msgPackage = new MessagePackage() { ConnectType = (int)ConnectType.LoginOn, Name = this.txtName.Text, Msg = loginOnStr };
            string szJson = JsonSerializer<MessagePackage>.GetObjectToJson(msgPackage);

            _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint serverInfo = new IPEndPoint(IPAddress.Parse("192.168.20.58"), 9090);

            _clientSocket.Connect(serverInfo);
            _clientSocket.Send(Encoding.UTF8.GetBytes(szJson));

            _unit.MsgBuffer = new Byte[65535];
            _clientSocket.BeginReceive(_unit.MsgBuffer, 0, _unit.MsgBuffer.Length, SocketFlags.None, ReceiveCallback, _clientSocket);
        }

        public void ReceiveCallback(IAsyncResult ar)
        {
            Socket socket = (Socket)ar.AsyncState;
            if (!socket.Connected)
                return;

            int read = socket.EndReceive(ar);
            if (read > 0)
            {
                //反序列化
                MessagePackage msgPackage = JsonSerializer<MessagePackage>.GetJsonToObject(_unit.MsgBuffer);
                switch (msgPackage.ConnectType)
                {
                    case (int)ConnectType.LoginOn:
                        if (msgPackage.Msg != string.Empty)
                        {
                            List<string> onlineUserList = JsonSerializer<List<string>>.GetJsonToObject(msgPackage.Msg);

                            if (this.InvokeRequired)
                            {
                                ShowMainWindows sw = new ShowMainWindows(ShowMainWindow);
                                this.Invoke(sw, onlineUserList.Count, onlineUserList);

                                _main.AssReceiveMsg(msgPackage.Name + "进入聊天室！\n");
                            }
                        }
                        else
                        {
                            socket.Shutdown(SocketShutdown.Both);
                            //关闭套接字，不允许重用
                            socket.Disconnect(false);
                            socket.Close();
                            MessageBox.Show("用户名或密码错误");
                        }
                        break;
                    case (int)ConnectType.GroupMsg:
                        _main.AssReceiveMsg(msgPackage.Msg);
                        break;
                    case (int)ConnectType.Exit:
                        List<string> temp = JsonSerializer<List<string>>.GetJsonToObject(msgPackage.Msg);
                        if (this.InvokeRequired)
                        {
                            ShowMainWindows sw = new ShowMainWindows(ShowMainWindow);
                            this.Invoke(sw, temp.Count, temp);
                        }
                        _main.AssReceiveMsg(msgPackage.Name + "离开了聊天室！\n");
                        break;
                    case (int)ConnectType.LaunchWhisper:
                        ShowWhisperWindows s = new ShowWhisperWindows(ShowWhidperWindow);
                        this.Invoke(s, msgPackage.Name, msgPackage.Msg);
                        break;
                    case (int)ConnectType.WhisperMsg:
                        string msg = msgPackage.Msg.Split(';')[1];
                        _main.AssReceiveMsg(msgPackage.Msg);
                        break;
                }
            }
            _unit.MsgBuffer = new Byte[65535];
            socket.BeginReceive(_unit.MsgBuffer, 0, _unit.MsgBuffer.Length, SocketFlags.None, ReceiveCallback, socket);
        }

        private void ShowMainWindow(int onlineUserNum, List<string> onlineUserList)
        {
            if (_isShow == false)
            {
                this.Hide();
                _main = new Main(this.txtName.Text, _clientSocket);//onlineUserNum, onlineUserList);
                _main.Show();
                _isShow = true;
            }
            if (_main != null)
            {
                _main.AssOnlineUser(onlineUserNum, onlineUserList);
            }
        }

        private void ShowWhidperWindow(string windowsName, string hostAndPort)
        {
            Whisper whidper = new Whisper(hostAndPort, _clientSocket) { Text = windowsName };
            whidper.Show();
        }
    }
}
